]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
loginDialog: On login, allow logout a conflicting session
authorJoan Torres <joan.torres@suse.com>
Wed, 7 Feb 2024 12:05:17 +0000 (13:05 +0100)
committerRay Strode <halfline@gmail.com>
Thu, 29 Feb 2024 20:42:52 +0000 (20:42 +0000)
When opening a session, find if there's already a session opened for the
same user with the help of Loginmanager.
When it's found, display the conflicting session dialog.

The logout dialog allows shutting down the conflicting session using the
greeter dbus method "StopConflictingSession".

If the dialog is already opened and the conflicting session has been
closed on its side, the new session will start.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3134>

js/gdm/loginDialog.js

index 09b68b42f1fa0a24fcf4e840af2d17898bebe891..c0ded7506100c1e0b8790ae8414adebe84919c5f 100644 (file)
@@ -1071,6 +1071,30 @@ export const LoginDialog = GObject.registerClass({
         }, this);
     }
 
+    _showConflictingSessionDialog(serviceName, conflictingSession) {
+        let conflictingSessionDialog = new ConflictingSessionDialog(conflictingSession,
+            this._greeterSessionProxy,
+            this._user.get_user_name());
+
+        conflictingSessionDialog.connect('cancel', () => {
+            this._authPrompt.reset();
+            conflictingSessionDialog.close();
+        });
+        conflictingSessionDialog.connect('force-stop', () => {
+            this._greeter.call_stop_conflicting_session_sync(null);
+        });
+
+        const loginManager = LoginManager.getLoginManager();
+        loginManager.connectObject('session-removed', (lm, sessionId) => {
+            if (sessionId === conflictingSession.Id) {
+                conflictingSessionDialog.close();
+                this._authPrompt.finish(() => this._startSession(serviceName));
+            }
+        }, conflictingSessionDialog);
+
+        conflictingSessionDialog.open();
+    }
+
     _startSession(serviceName) {
         this._bindOpacity();
         this.ease({
@@ -1084,7 +1108,40 @@ export const LoginDialog = GObject.registerClass({
         });
     }
 
-    _onSessionOpened(client, serviceName) {
+    async _findConflictingSession(ignoreSessionId) {
+        const userName = this._user.get_user_name();
+        const loginManager = LoginManager.getLoginManager();
+        const sessions = await loginManager.listSessions();
+        for (const session of sessions.map(([id, , user, , path]) => ({id, user, path}))) {
+            if (ignoreSessionId === session.id)
+                continue;
+
+            if (userName !== session.user)
+                continue;
+
+            const sessionProxy = loginManager.getSession(session.path);
+
+            if (sessionProxy.Type !== 'wayland' && sessionProxy.Type !== 'x11')
+                continue;
+
+            if (sessionProxy.State !== 'active' && sessionProxy.State !== 'online')
+                continue;
+
+            return sessionProxy;
+        }
+
+        return null;
+    }
+
+    async _onSessionOpened(client, serviceName, sessionId) {
+        if (sessionId) {
+            const conflictingSession = await this._findConflictingSession(sessionId);
+            if (conflictingSession) {
+                this._showConflictingSessionDialog(serviceName, conflictingSession);
+                return;
+            }
+        }
+
         this._authPrompt.finish(() => this._startSession(serviceName));
     }